package com.ikun.admin.common.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.ikun.admin.modules.gen.entity.CodeConfig;
import com.ikun.admin.modules.gen.entity.Table;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName GenerateCode
 * @Description:
 * @CreateDate: 2024/4/13 23:21
 */
public class GenerateCode {

    private static final IdType DEFAULT_IDTYPE = IdType.ASSIGN_ID;

    private static final String PACKAGE_PREFIX = "com.ikun.admin.modules.";

    private static final String DEFAULT_ROOT_PATH =System.getProperty("user.dir") + "\\ikun-admin\\src\\main\\java";

    private static Map<Integer, IdType> ID_TYPE_MAP = new HashMap<>();
    private static Map<String, DbType> BD_TYPE_MAP = new HashMap<>();

    static {
        ID_TYPE_MAP.put(IdType.AUTO.getKey(), IdType.AUTO);
        ID_TYPE_MAP.put(IdType.NONE.getKey(), IdType.NONE);
        ID_TYPE_MAP.put(IdType.INPUT.getKey(), IdType.INPUT);
        ID_TYPE_MAP.put(IdType.ASSIGN_ID.getKey(), IdType.ASSIGN_ID);
        ID_TYPE_MAP.put(IdType.ASSIGN_UUID.getKey(), IdType.ASSIGN_UUID);
        ID_TYPE_MAP.put(IdType.ASSIGN_UUID.getKey(), IdType.ASSIGN_UUID);

        BD_TYPE_MAP.put(DbType.MYSQL.getDb(), DbType.MYSQL);
        BD_TYPE_MAP.put(DbType.ORACLE.getDb(), DbType.ORACLE);
        BD_TYPE_MAP.put(DbType.DB2.getDb(), DbType.DB2);
        BD_TYPE_MAP.put(DbType.H2.getDb(), DbType.H2);
        BD_TYPE_MAP.put(DbType.SQL_SERVER.getDb(), DbType.SQL_SERVER);
    }

    /**
     * module:模块
     * packagePath:包路径
     *
     */
    public static String generateCode(CodeConfig codeConfig, DruidDataSource druidDataSource, List<Table> tableList) {


        AutoGenerator generator = new AutoGenerator();
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(Optional.ofNullable(codeConfig.getRootPath()).orElse(DEFAULT_ROOT_PATH));
        gc.setOpen(false);
        // 主键策略
        Integer idType = codeConfig.getIdType();
        gc.setIdType(Optional.ofNullable(idType).map(ID_TYPE_MAP::get).orElse(DEFAULT_IDTYPE));
        gc.setServiceName("%sService");
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);
        gc.setSwagger2(true);
        generator.setGlobalConfig(gc);

        DataSourceConfig ds = new DataSourceConfig();
        ds.setUrl(druidDataSource.getUrl());
        ds.setUsername(druidDataSource.getUsername());
        ds.setPassword(druidDataSource.getPassword());
        ds.setDriverName(druidDataSource.getDriverClassName());
        String dbType = druidDataSource.getDbType();

        ds.setDbType(Optional.ofNullable(dbType).map(BD_TYPE_MAP::get).orElse(DbType.MYSQL));
        PackageConfig pc = new PackageConfig();
        // 包路径
        pc.setParent(PACKAGE_PREFIX + codeConfig.getModule());
        pc.setEntity("entity");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setController("controller");
        generator.setPackageInfo(pc);
        StrategyConfig sc = new StrategyConfig();
        List<String> tableValueList = tableList.stream().map(Table::getTableValue).collect(Collectors.toList());
        String[] tableValueArray = tableValueList.toArray(new String[0]);
        sc.setInclude(tableValueArray);
        sc.setColumnNaming(NamingStrategy.underline_to_camel);
        sc.setCapitalMode(true);
        sc.setNaming(NamingStrategy.underline_to_camel);
        sc.setSuperServiceClass("");
        sc.setEntityLombokModel(true);
        sc.setRestControllerStyle(true);
        sc.setEntityLombokModel(true);
        sc.setTablePrefix(codeConfig.getModule());
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(new TableFill("creator", FieldFill.INSERT));
        tableFills.add(new TableFill("create_date", FieldFill.INSERT));
        tableFills.add(new TableFill("updater", FieldFill.INSERT_UPDATE));
        tableFills.add(new TableFill("update_date", FieldFill.INSERT_UPDATE));
        sc.setTableFillList(tableFills);
        generator.setStrategy(sc);
        generator.setDataSource(ds);
        generator.execute();

        String result = gc.getOutputDir() + "\\" + PACKAGE_PREFIX;
        return (result.replace(".", "\\").substring(0, result.length() - 1) + "\\" + codeConfig.getModule()).replace("\\", "/");

    }


}
